.TH std::atomic 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::atomic \- std::atomic

.SH Synopsis
   Defined in header <memory>
   template< class T >                      \fI(since C++20)\fP
   struct std::atomic<std::shared_ptr<T>>;

   The partial template specialization of std::atomic for std::shared_ptr<T> allows
   users to manipulate shared_ptr objects atomically.

   If multiple threads of execution access the same std::shared_ptr object without
   synchronization and any of those accesses uses a non-const member function of
   shared_ptr then a data race will occur unless all such access is performed through
   an instance of std::atomic<std::shared_ptr> (or, deprecated as of C++20, through the
   standalone functions for atomic access to std::shared_ptr).

   Associated use_count increments are guaranteed to be part of the atomic operation.
   Associated use_count decrements are sequenced after the atomic operation, but are
   not required to be part of it, except for the use_count change when overriding
   expected in a failed CAS. Any associated deletion and deallocation are sequenced
   after the atomic update step and are not part of the atomic operation.

   Note that the control block of a shared_ptr is thread-safe: different non-atomic
   std::shared_ptr objects can be accessed using mutable operations, such as operator=
   or reset, simultaneously by multiple threads, even when these instances are copies,
   and share the same control block internally.

   The type T may be an incomplete type.

.SH Member types

   Member type Definition
   value_type  std::shared_ptr<T>

.SH Member functions

   All non-specialized std::atomic functions are also provided by this specialization,
   and no additional member functions.

atomic<shared_ptr<T>>::atomic

   constexpr atomic() noexcept = default;                    \fB(1)\fP
   constexpr atomic( std::nullptr_t ) noexcept : atomic() {} \fB(2)\fP
   atomic( std::shared_ptr<T> desired ) noexcept;            \fB(3)\fP
   atomic( const atomic& ) = delete;                         \fB(4)\fP

   1,2) Initializes the underlying shared_ptr<T> to the null value.
   3) Initializes the underlying shared_ptr<T> to a copy of desired. As with any
   std::atomic type, initialization is not an atomic operation.
   4) Atomic types are not copy/move constructible.

atomic<shared_ptr<T>>::operator=

   void operator=( const atomic& ) = delete;              \fB(1)\fP
   void operator=( std::shared_ptr<T> desired ) noexcept; \fB(2)\fP
   void operator=( std::nullptr_t ) noexcept;             \fB(3)\fP

   1) Atomic types are not copy/move assignable.
   2) Value assignment, equivalent to store(desired).
   3) Resets the atomic shared pointer to null pointer value. Equivalent to
   store(nullptr);.

atomic<shared_ptr<T>>::is_lock_free

   bool is_lock_free() const noexcept;

   Returns true if the atomic operations on all objects of this type are lock-free,
   false otherwise.

atomic<shared_ptr<T>>::store

   void store( std::shared_ptr<T> desired,
               std::memory_order order = std::memory_order_seq_cst ) noexcept;

   Atomically replaces the value of *this with the value of desired as if by
   p.swap(desired) where p is the underlying std::shared_ptr<T>. Memory is ordered
   according to order. The behavior is undefined if order is std::memory_order_consume,
   std::memory_order_acquire, or std::memory_order_acq_rel.

atomic<shared_ptr<T>>::load

   std::shared_ptr<T> load( std::memory_order order = std::memory_order_seq_cst )
   const noexcept;

   Atomically returns a copy of the underlying shared pointer. Memory is ordered
   according to order. The behavior is undefined if order is std::memory_order_release
   or std::memory_order_acq_rel.

atomic<shared_ptr<T>>::operator std::shared_ptr<T>

   operator std::shared_ptr<T>() const noexcept;

   Equivalent to return load();.

atomic<shared_ptr<T>>::exchange

   std::shared_ptr<T> exchange( std::shared_ptr<T> desired,
                                std::memory_order order = std::memory_order_seq_cst )
   noexcept;

   Atomically replaces the underlying std::shared_ptr<T> with desired as if by
   p.swap(desired) where p is the underlying std::shared_ptr<T> and returns a copy of
   the value that p had immediately before the swap. Memory is ordered according to
   order. This is an atomic read-modify-write operation.

atomic<shared_ptr<T>>::compare_exchange_weak, compare_exchange_strong

   bool compare_exchange_strong( std::shared_ptr<T>& expected, std::shared_ptr<T>
   desired,                                                                        \fB(1)\fP
                                 std::memory_order success, std::memory_order
   failure ) noexcept;
   bool compare_exchange_weak( std::shared_ptr<T>& expected, std::shared_ptr<T>
   desired,                                                                        \fB(2)\fP
                               std::memory_order success, std::memory_order
   failure ) noexcept;
   bool compare_exchange_strong( std::shared_ptr<T>& expected, std::shared_ptr<T>
   desired,                                                                        \fB(3)\fP
                                 std::memory_order order =
   std::memory_order_seq_cst ) noexcept;
   bool compare_exchange_weak( std::shared_ptr<T>& expected, std::shared_ptr<T>
   desired,                                                                        \fB(4)\fP
                               std::memory_order order = std::memory_order_seq_cst
   ) noexcept;

   1) If the underlying std::shared_ptr<T> stores the same T* as expected and shares
   ownership with it, or if both underlying and expected are empty, assigns from
   desired to the underlying std::shared_ptr<T>, returns true, and orders memory
   according to success, otherwise assigns from the underlying std::shared_ptr<T> to
   expected, returns false, and orders memory according to failure. The behavior is
   undefined if failure is std::memory_order_release or std::memory_order_acq_rel. On
   success, the operation is an atomic read-modify-write operation on *this and
   expected is not accessed after the atomic update. On failure, the operation is an
   atomic load operation on *this and expected is updated with the existing value read
   from the atomic object. This update to expected's use_count is part of this atomic
   operation, although the write itself (and any subsequent deallocation/destruction)
   is not required to be.
   2) Same as \fB(1)\fP, but may also fail spuriously.
   3) Equivalent to: return compare_exchange_strong(expected, desired, order,
   fail_order);, where fail_order is the same as order except that
   std::memory_order_acq_rel is replaced by std::memory_order_acquire and
   std::memory_order_release is replaced by std::memory_order_relaxed.
   4) Equivalent to: return compare_exchange_weak(expected, desired, order,
   fail_order);, where fail_order is the same as order except that
   std::memory_order_acq_rel is replaced by std::memory_order_acquire and
   std::memory_order_release is replaced by std::memory_order_relaxed.

atomic<shared_ptr<T>>::wait

   void wait( std::shared_ptr<T> old,
              std::memory_order order = std::memory_order_seq_cst ) const noexcept;

   Performs an atomic waiting operation.

   Compares load(order) with old and if they are equivalent then blocks until *this is
   notified by notify_one() or notify_all(). This is repeated until load(order)
   changes. This function is guaranteed to return only if value has changed, even if
   underlying implementation unblocks spuriously.

   Memory is ordered according to order. The behavior is undefined if order is
   std::memory_order_release or std::memory_order_acq_rel.

   Notes: two shared_ptrs are equivalent if they store the same pointer and either
   share ownership or are both empty.

atomic<shared_ptr<T>>::notify_one

   void notify_one() noexcept;

   Performs an atomic notifying operation.

   If there is a thread blocked in atomic waiting operations (i.e. wait()) on *this,
   then unblocks at least one such thread; otherwise does nothing.

atomic<shared_ptr<T>>::notify_all

   void notify_all() noexcept;

   Performs an atomic notifying operation.

   Unblocks all threads blocked in atomic waiting operations (i.e. wait()) on *this, if
   there are any; otherwise does nothing.

.SH Member constants

   The only standard std::atomic member constant is_always_lock_free is also provided
   by this specialization.

atomic<shared_ptr<T>>::is_always_lock_free

   static constexpr bool is_always_lock_free = /*implementation-defined*/;

.SH Notes

       Feature-test macro       Value    Std             Feature
   __cpp_lib_atomic_shared_ptr 201711L (C++20) std::atomic<std::shared_ptr>

.SH Example

    This section is incomplete
    Reason: no example

   Defect reports

   The following behavior-changing defect reports were applied retroactively to
   previously published C++ standards.

      DR    Applied to        Behavior as published              Correct behavior
   LWG 3661 C++20      atomic<shared_ptr<T>> was not        made constant-initializable
                       constant-initializable from nullptr
   LWG 3893 C++20      LWG3661 made atomic<shared_ptr<T>>   assignability restored
                       not assignable from nullptr_t

.SH See also

           atomic class template and specializations for bool, integral,
   atomic  floating-point,
   \fI(C++11)\fP \fI(since C++20)\fP and pointer types
           \fI(class template)\fP

.SH Category:
     * Todo no example
